﻿using System;
using System.Collections.Generic;
using System.Linq;
using GCTrackableRace.Interfaces;
using Microsoft.Practices.Unity;
using System.Reflection;

namespace GcTrackableRace.ScoreCalculator
{
	public class RaceRules
	{
		public RaceRules(IUnityContainer unityContainer, IProgramConfigurationSettings programConfigurationSettings)
		{
			UnityContainer = unityContainer;
			ProgramConfigurationSettings = programConfigurationSettings;
			//LocationInfoLookup = unityContainer.Resolve<ILocationInfoLookup>("SingletonLocationInfoLookup");
			LocationInfoLookup = unityContainer.Resolve<ILocationInfoLookup>();
		}

		private IUnityContainer UnityContainer { get; set; }
		private IProgramConfigurationSettings ProgramConfigurationSettings { get; set; }
		private ILocationInfoLookup LocationInfoLookup { get; set; }

		public IEnumerable<IRaceRule> Create()
		{
			var raceRules = new List<IRaceRule>();

			var rawRaceRules = ProgramConfigurationSettings.RaceRuleParameters;

			for (int i = 0; i < rawRaceRules.Count(); i++)
			{
				var constructorParameters = new List<ResolverOverride>();
				var raceRuleName = string.Empty;

				for (int j = 0; j < rawRaceRules[i].Count; j++)
				{
					if (j == 0)
					{
						raceRuleName = rawRaceRules[i][j].Item2.Trim();
					}
					else
					{
						constructorParameters.Add(new ParameterOverride(rawRaceRules[i][j].Item1.Trim(), rawRaceRules[i][j].Item2.Trim()));
					}
				}

				var objType = Assembly.Load("GcTrackableRace.ScoreCalculator").GetTypes().First(t => t.Name == raceRuleName);

				try
				{
					var rule = (IRaceRule)UnityContainer.Resolve(objType, constructorParameters.ToArray());
					
					raceRules.Add(rule);
				}
				catch (Exception)
				{
					throw;
				}

			}

			return raceRules.AsReadOnly();
		}
	}
}